home *** CD-ROM | disk | FTP | other *** search
- /*
- * HeliosMouse.c Installs an input handler that activates windows when
- * you move the mouse over inactive ones.
- *
- * Copyright (c) 1987 by Davide P. Cervone
- * You may use this code provided this copyright notice is left intact.
- */
-
- #include <exec/types.h>
- #include <libraries/dos.h>
- #include <exec/io.h>
- #include <exec/memory.h>
- #include <exec/interrupts.h>
- #include <devices/input.h>
- #include <devices/inputevent.h>
-
- static char *program = "HeliosMouse";
- static char *version = "v1.0";
- static char *date = "June 1987";
- static char *author = "Copyright (c) 1987 by Davide P. Cervone";
-
- static char *PortName = "HeliosPort";
- static char *handler = "L:Helios-Handler"; /* the handler file */
- #define HANDLER &(handler[2]) /* without the "L:" */
-
-
- /*
- * This is the structure that holds the handler information between calls
- * to HeliosMouse. We create a named, public message-port that points to
- * an instance of this structure so that we can find this information
- * when we are asked to remove the handler. The PortName is stored here
- * (NamedPort->mp_Node.ln_Name uses this area for its name). The other
- * data are what we need in order to remove the handler and clean up properly.
- */
-
- struct HandlerBlock
- {
- char *PortName; /* name of the public, named message-port */
- struct Interrupt Handler; /* the handler added to the handler chain */
- struct IntuitionBase *Ibase; /* library base used by the handler */
- struct LayersBase *Lbase; /* library base used by the handler */
- long Segment; /* pointer from LoadSeg() */
- };
- #define HANDLERINFOSIZE sizeof(struct HandlerBlock)
- #define NAMESIZE (strlen(PortName)+1)
-
- extern struct MsgPort *CreatePort();
- extern struct IOStdReq *CreateStdIO();
- extern struct MsgPort *FindPort(), *CreatePort();
- extern APTR AllocMem();
- extern long LoadSeg();
-
- #define INTUITION_REV 0L
- #define LAYERS_REV 0L
-
- struct IntuitionBase *IntuitionBase = NULL;
- struct LayersBase *LayersBase = NULL;
- extern struct SysBase *SysBase;
-
- struct MsgPort *InputPort = NULL; /* Port used to talk to Input.Device */
- struct IOStdReq *InputBlock = NULL; /* request block used with Input.Device */
- LONG InputDevice = 0; /* flag whether Input.Device is open */
- struct MsgPort *NamedPort = NULL; /* holds info needed to remove handler */
- struct HandlerBlock *HandlerInfo = NULL; /* holds info stored in NamedPort */
-
-
- /*
- * DoExit()
- *
- * General purpose exit routine. If 's' is not NULL, then print an
- * error message with up to three parameters. Free any memory, close
- * any open device, delete any ports, close any libraries, etc.
- */
-
- void DoExit(s,x1,x2,x3)
- char *s, *x1, *x2, *x3;
- {
- long status = RETURN_OK;
-
- if (s != NULL)
- {
- printf(s,x1,x2,x3);
- printf("\n");
- status = RETURN_ERROR;
- }
- if (InputDevice) CloseDevice(InputBlock);
- if (InputBlock) DeleteStdIO(InputBlock);
- if (InputPort) DeletePort(InputPort);
- if (NamedPort) DeletePort(NamedPort);
- if (HandlerInfo)
- {
- if (HandlerInfo->PortName) FreeMem(HandlerInfo->PortName,NAMESIZE);
- FreeMem(HandlerInfo,HANDLERINFOSIZE);
- }
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- if (LayersBase) CloseLibrary(LayersBase);
- exit(status);
- }
-
-
- /*
- * CheckLibOpen()
- *
- * General library open routine. It opens a library and sets a pointer
- * to it. It checks that the library was openned successfully.
- */
-
- void CheckLibOpen(lib,name,rev)
- APTR *lib;
- char *name;
- int rev;
- {
- extern APTR OpenLibrary();
-
- if ((*lib = OpenLibrary(name,(LONG)rev)) == NULL)
- DoExit("Can't open '%s'\n",name);
- }
-
-
- /*
- * Macros that make memory allocation easier.
- */
- #define NEW(s,var) (var = (struct s *)New("var",sizeof(struct s)))
- #define NEWCHAR(var,s) (var = (char *)New("var",s))
-
-
- /*
- * New()
- *
- * Allocate public memory of a given size and set it to all zeros. If there
- * is not enough memory, then exit with an error, otherwise return the
- * pointer to the newly allocated memory.
- */
-
- APTR New(name,size)
- char *name;
- int size;
- {
- APTR ptr;
-
- if ((ptr = AllocMem(size,MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
- DoExit("Can't Get Memory for '%s'");
- return(ptr);
- }
-
-
- /*
- * TellInputDevice()
- *
- * Create a port and I/O block, and open the input device. Set up the
- * I/O block to add or remove the input handler, and send the request
- * to the input device. Finally, close the device and delete the
- * I/O block and port.
- */
-
- void TellInputDevice(function)
- int function;
- {
- long status;
-
- if ((InputPort = CreatePort(0,0)) == NULL) DoExit("Can't Create Port");
- if ((InputBlock = CreateStdIO(InputPort)) == NULL)
- DoExit("Can't Create Standard IO Block");
- InputDevice = (OpenDevice("input.device",0,InputBlock,0) == 0);
- if (InputDevice == FALSE) DoExit("Can't Open 'input.device'");
-
- InputBlock->io_Command = (long) function;
- InputBlock->io_Data = (APTR) &(HandlerInfo->Handler);
- if (status = DoIO(InputBlock)) DoExit("Error from DoIO: %ld",status);
-
- CloseDevice(InputBlock);
- DeleteStdIO(InputBlock);
- DeletePort(InputPort);
- }
-
-
- /*
- * CreateHandler()
- *
- * Open the libraries needed by the input handler and store their locations
- * in the HandlerInfo structure (so we can close them later). Try to
- * LoadSeg() the handler. If it is not in the current directory, try the
- * L: directory. Exit with an error if the handler can't be found.
- * Convert the segment pointer into a pointer to the Setup routine (the
- * first routine in the handler executable). Call Setup() and pass it
- * the pointers to the libraries that it will need to use. Setup() returns
- * a pointer to the actual handler routine that should be added into the
- * input handler chain. Store this in the HandlerInfo structure so we
- * can use it to remove the handler later. Set the handler priority to
- * 51 so that it is ahead of Intuition.
- *
- * Finally, add the handler in the chain and tell the user that the
- * handler has been installed.
- */
-
- void CreateHandler()
- {
- long (*Setup)();
-
- CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
- CheckLibOpen(&LayersBase,"layers.library",LAYERS_REV);
-
- HandlerInfo->Ibase = IntuitionBase;
- HandlerInfo->Lbase = LayersBase;
- if ((HandlerInfo->Segment = LoadSeg(HANDLER)) == NULL)
- if ((HandlerInfo->Segment = LoadSeg(handler)) == NULL)
- DoExit("Can't Load '%s'",handler);
- Setup = (long (*)()) ((HandlerInfo->Segment << 2) + 4);
- HandlerInfo->Handler.is_Code =
- (void (*)()) ((*Setup)(IntuitionBase,LayersBase,SysBase));
- HandlerInfo->Handler.is_Node.ln_Pri = 51;
-
- TellInputDevice(IND_ADDHANDLER);
- printf("%s %s (%s) Installed\n",program,version,date);
- }
-
-
- /*
- * Delete Handler()
- *
- * Retreive the library pointers from the HandlerInfo structure where
- * we stored them when we originally installed the handler, then remove
- * the handler from the input handler chain. Tell the user that the
- * handler is gone and then close the libraries that are no longer needed.
- */
-
- void DeleteHandler()
- {
- IntuitionBase = HandlerInfo->Ibase;
- LayersBase = HandlerInfo->Lbase;
-
- TellInputDevice(IND_REMHANDLER);
- UnLoadSeg(HandlerInfo->Segment);
- printf("%s Removed\n",program);
-
- CloseLibrary(IntuitionBase);
- CloseLibrary(LayersBase);
- }
-
-
- /*
- * main()
- *
- * Check if a message port with our name already exists.
- * If not, then the handler is not already installed, so:
- * Allocate a new HandlerInfo structure and initialize the port name.
- * Create a public, names message-port (we will look for this the next
- * time HeliosMouse is called).
- * Make the message port point to the HandlerInfo structure so we
- * can use it later when the user asks us to remove the handler.
- * Note that the port is not actually used for putting and getting
- * messages, so the Task field is never used, so we can take it for
- * our own uses.
- * Finally, add the input handler into the chain.
- * Otherwise, the port exists, so HeliosMouse already is installed:
- * Retreive the HandlerInfo poiner from the port, and
- * remove the handler from the input handler chain.
- * Free the memory used by the HandlerInfo, and delete the message port.
- */
-
- void main()
- {
- NamedPort = FindPort(PortName);
- if (NamedPort == NULL)
- {
- NEW(HandlerBlock,HandlerInfo);
- NEWCHAR(HandlerInfo->PortName,NAMESIZE);
- strcpy(HandlerInfo->PortName,PortName);
- if ((NamedPort = CreatePort(HandlerInfo->PortName,0)) == NULL)
- DoExit("Can't Create Message Port '%s'",PortName);
- NamedPort->mp_SigTask = (struct Task *)HandlerInfo;
- CreateHandler();
- } else {
- HandlerInfo = (struct HandlerBlock *)(NamedPort->mp_SigTask);
- DeleteHandler();
- FreeMem(HandlerInfo->PortName,NAMESIZE);
- FreeMem(HandlerInfo,HANDLERINFOSIZE);
- DeletePort(NamedPort);
- }
- }
-